/*
 * ADC.c
 *
 * Created: 9/04/2012 4:05:11 PM
 *  Author: Richard
 */ 
#include <avr/interrupt.h>
#include <string.h>

#include "ADC.h"

static volatile uint16 u16ADCValue[ADC_nenNumberOfChannels][ADC_nBufferSize];
static uint8 u8Index[2];
static uint8 u8Channel = 0;

ISR(ADC_vect)
{
	uint16_bits u16ADCResult;
	
	/* Get result */
	u16ADCResult.byte.hb = ADCH;
	u16ADCResult.byte.lb = ADCL;
	
	/* Store result and change channel */
	switch( ADMUX )
	{
		case 0:
			u16ADCValue[0][0] = u16ADCResult.value;
			ADMUX = 1;
			break;
		case 1:
			u16ADCValue[1][0] = u16ADCResult.value;
			ADMUX = 0;
			break;
		default:
			break;
	}
	
	DIO_vSetOutputLevel( DIO_nenLED3, ADMUX );
}

void ADC_vInit( void )
{
	ADCSRA = ( 1 << ADEN ) | ( 1 << ADATE ) | ( 1 << ADIE ) | ( 1 << ADPS2 ) | ( 1 << ADPS1 ) | ( 1 << ADPS0 );
	ADMUX = 0x00;
	ADCSRA |= ( 1 << ADSC );
	
	memset( &u16ADCValue, 0x00, sizeof(u16ADCValue) );
	memset( &u8Index, 0x00, sizeof(u8Index) );
}

uint16 ADC_u16GetValue( ADC_tenChannels enChannel )
{
	uint16 u16ReturnValue = 0;
	
	/* pause interrupt */
	ADCSRA &= ~( 1 << ADIE );
	/* read adc value from module */	
	u16ReturnValue = u16ADCValue[enChannel][0];		
	/* resume interrupt */
	ADCSRA |= ( 1 << ADIE );
	
	return u16ReturnValue;
}

DIO_tenLogicLevel ADC_enGetLogicValue( DIO_tenPinName enPinName )
{
	DIO_tenLogicLevel enReturnValue = tLo;
	uint16 u16ADCValue;
	
	switch( enPinName )
	{
		case DIO_nenCurrent:
			u16ADCValue = ADC_u16GetValue(ADC_nenCurrent);
			enReturnValue = ( u16ADCValue > 0x7F ) ? tHi : tLo;
			break;
		default:
			break;
	}		

	return enReturnValue;
}	
